package com.ztesoft.zsmart.zcm.metrics.utils;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import com.ztesoft.zsmart.core.log.ZSmartLogger;
import com.ztesoft.zsmart.zcm.core.remote.RestClient;
import com.ztesoft.zsmart.zcm.metrics.config.MetricsStorageProperties;

public final class CrmsCache implements Runnable {

    private static final ZSmartLogger logger = ZSmartLogger.getLogger(CrmsCache.class);

    private static Map<String, Object> regionCache = new ConcurrentHashMap<>();

    private static Map<String, Object> projectIdCache = new ConcurrentHashMap<>();

    private static Map<String, Object> organizationCache = new ConcurrentHashMap<>();

    private static Map<String, Object> applicantCache = new ConcurrentHashMap<>();

    private static Map<String, Object> projectNameCache = new ConcurrentHashMap<>();

    private int refreshTime = SpringContextUtil.getBean(MetricsStorageProperties.class).getClusterRefreshTime();

    private static String crmsUrl;

    @Override
    public void run() {
        if (SpringContextUtil.getBean(MetricsStorageProperties.class).getMetricsTranslatorType().length > 1) {
            while (true) {
                fresh();
                // 等待刷新
                try {
                    Thread.sleep(refreshTime * 60 * 1000L);
                }
                catch (InterruptedException e) {
                    logger.error("refresh crms cache error:", e);
                }
            }
        }
    }

    public static String getProjectIdByIp(String ip) {
        String projectId = "unkown";
        try {
            if (!MapUtils.isEmpty(projectIdCache) && projectIdCache.get(ip) != null) {
                projectId = String.valueOf(projectIdCache.get(ip));
            }
        }
        catch (Exception e) {
            logger.error("read project id cache error:", e);
        }
        return projectId;
    }

    public static String getProjectNameByIp(String ip) {
        String param = "unkown";
        try {
            if (!MapUtils.isEmpty(projectNameCache) && projectNameCache.get(ip) != null) {
                param = String.valueOf(projectNameCache.get(ip));
            }
        }
        catch (Exception e) {
            logger.error("read project name cache error:", e);
        }
        return param;
    }

    public static String getApplicantNameByIp(String ip) {
        String param = "unkown";
        try {
            if (!MapUtils.isEmpty(applicantCache) && applicantCache.get(ip) != null) {
                param = String.valueOf(applicantCache.get(ip));
            }
        }
        catch (Exception e) {
            logger.error("read applicant cache error:", e);
        }
        return param;
    }

    public static String getOrganizationIdByIp(String ip) {
        String param = "-1";
        try {
            if (!MapUtils.isEmpty(organizationCache) && organizationCache.get(ip) != null) {
                param = String.valueOf(organizationCache.get(ip));
            }
        }
        catch (Exception e) {
            logger.error("read organization cache error:", e);
        }
        return param;
    }

    public static String getRegionIdByIp(String ip) {
        String region = "unkown";
        try {
            if (!MapUtils.isEmpty(regionCache) && regionCache.get(ip) != null) {
                region = String.valueOf(regionCache.get(ip));
            }
        }
        catch (Exception e) {
            logger.error("read region cache error:", e);
        }
        return region;
    }

    public static void refresh() {
        fresh();
    }

    private static void fresh() {
        Map<String, Object> cacheMapTempProjectId = new ConcurrentHashMap<>();
        Map<String, Object> cacheMapTempRegion = new ConcurrentHashMap<>();
        Map<String, Object> cacheMapTempOrganization = new ConcurrentHashMap<>();
        Map<String, Object> cacheMapTempApplicantCache = new ConcurrentHashMap<>();
        Map<String, Object> cacheMapTempProjectName = new ConcurrentHashMap<>();
        try {
            logger.info("start refresh cluster-ip cache");
            if (crmsUrl == null) {
                crmsUrl = SpringContextUtil.getBean(MetricsStorageProperties.class).getCrmsUrl()
                    + "/cloud-servers/ip-list";
            }
            List<Map> rows = SpringContextUtil.getBean(RestClient.class).getForObject(crmsUrl, List.class);
            if (CollectionUtils.isNotEmpty(rows)) {
                rows.forEach(row -> {
                    String ip = String.valueOf(row.get("ip"));
                    if (row.get("ip") != null) {
                        addParam(cacheMapTempProjectId, cacheMapTempRegion, cacheMapTempOrganization,
                            cacheMapTempApplicantCache, cacheMapTempProjectName, row, ip);
                    }
                });
            }

        }
        catch (Exception e) {
            logger.error("get crms cacheMap error:", e);
        }
        try {
            if (MapUtils.isNotEmpty(cacheMapTempProjectId)) {
                projectIdCache.clear();
                projectIdCache.putAll(cacheMapTempProjectId);
            }
            if (MapUtils.isNotEmpty(cacheMapTempRegion)) {
                regionCache.clear();
                regionCache.putAll(cacheMapTempRegion);
            }
            if (MapUtils.isNotEmpty(cacheMapTempProjectName)) {
                projectNameCache.clear();
                projectNameCache.putAll(cacheMapTempProjectName);
            }
            if (MapUtils.isNotEmpty(cacheMapTempOrganization)) {
                organizationCache.clear();
                organizationCache.putAll(cacheMapTempOrganization);
            }
            if (MapUtils.isNotEmpty(cacheMapTempApplicantCache)) {
                applicantCache.clear();
                applicantCache.putAll(cacheMapTempApplicantCache);
            }
        }
        catch (Exception e) {
            logger.error("refresh crms cache error:", e);
        }
    }

    private static void addParam(Map<String, Object> cacheMapTempProjectId, Map<String, Object> cacheMapTempRegion,
        Map<String, Object> cacheMapTempOrganization, Map<String, Object> cacheMapTempApplicantCache,
        Map<String, Object> cacheMapTempProjectName, Map row, String ip) {
        if (row.get("projectId") != null) {
            cacheMapTempProjectId.put(ip, row.get("projectId"));
        }
        if (row.get("projectName") != null) {
            cacheMapTempProjectName.put(ip, row.get("projectName"));
        }
        if (row.get("region") != null) {
            cacheMapTempRegion.put(ip, row.get("region"));
        }
        if (row.get("organizationId") != null) {
            cacheMapTempOrganization.put(ip, row.get("organizationId"));
        }
        if (row.get("applicantName") != null) {
            cacheMapTempApplicantCache.put(ip, row.get("applicantName"));
        }
    }

}

